#!/usr/bin/python2.4
#
# Copyright 2011 Google Inc. All Rights Reserved.

"""One-line documentation for electricity module.

A detailed description of electricity.
"""

__author__ = 'bst@google.com (Ben Stewart)'

RIVER = 'javascript:PopupRiver'
RIVERLABELS = ['Station No','River Height (m)','Time of Observation','Flood Class','Tendency','Minor (m)','Moderate (m)','Major (m)']
RIVERELEMENTS = ['name', 'station','lat', 'long','height',
                 'floodClass','tendency', 'time','minorHeight','moderateHeight','majorHeight']

from BeautifulSoup import BeautifulSoup as BS
from django.utils import simplejson, html
from controllers import geocode
import datetime
import logging
import urllib

# qld
REGIONS = [45, 42, 55, 53, 57, 49, 44, 50, 51, 43]

def fixBr(o):
  if isinstance(o, basestring):
    return o
  elif o.name == 'br':
    return "\n"
  else:
    return ''

def fixBrList(l):
    return reduce(lambda a, b: a + b, map(fixBr, l))

def loadMaps():
  suburbs = {}
  for region in REGIONS:
    # TODO(bst): Up this range if we are presented with a lot of power outage pages.
    for pageno in xrange(1,3):
      url = ('http://www.energex.com.au/network/asp/unplanned_interruptions' +
             '.asp?cmd=regiondetail&id=%d&index=%d') % (region, pageno)
      logging.info('Fetching URL %s', url)
      raw = urllib.urlopen(url)
      page = BS(raw.read())

      for table in page.findAll('table'):
        if table['width'].startswith('95'):
          for row in filter(lambda r: not isinstance(r, basestring),
                            table.contents):

            cells = filter(lambda r: not isinstance(r, basestring), row)

            if len(cells) >= 5:
              if cells[0].name == 'td':
                data = {
                    'suburb': fixBrList(cells[0].contents),
                    'state': 'QLD',
                    'country': 'Australia',
                    'cause': fixBrList(cells[4].contents),
                    'fixtime': fixBrList(cells[2].contents),
                    }

                suburbs['%s, %s' % (data['suburb'], data['state'])] = data
                logging.debug('Added suburb %s, %s', data['suburb'],
                              data['state'])

  logging.info('Found %d suburbs', len(suburbs))
  # TODO(arb): sanitise the JSON
  return makeKml(suburbs.values())
  #return simplejson.dumps(l)

# HERE BE DRAGONS
# TODO(jmcgill): Replace with Fusion Tables when we have time to play with OAuth
# and verify that upload/drop is reliable.
def makeStyle(document, image, id):
  text = """<Style id="%s">
    <IconStyle>
      <Icon>
        <href>%s</href>
      </Icon>
    </IconStyle>
  </Style>
  """ % (id, image)
  document.append(text)

def makePoint(document, point):
  style = '#powerOutage'
  lat, lng, approx = geocode.GetLocation(('%s, %s, %s' % (point['suburb'],
                                                          point['state'],
                                                          'Australia')),
                                          point['state'])

  text = """<Placemark>
    <styleUrl>%s</styleUrl>
    <name>%s</name>
    <description>
      <![CDATA[
        <p><b>Electricity Outage: %s, %s</b></p>
        <p><b>Cause:</b> %s</p>
        <p><b>Restoration Time:</b> %s</p>
      ]]>
    </description>
    <Point>
      <coordinates>%s,%s</coordinates>
    </Point>
  </Placemark>""" % (style, html.escape(point['suburb']),
                     html.escape(point['suburb']),
                     html.escape(point['state']),
                     html.escape(point['cause']),
                     html.escape(point['fixtime']),
                     lat, lng)
  document.append(text)

def makeKml(data):
  # Why bother with the DOM when you can concat strings?
  document = []
  document.append("""<?xml version="1.0" encoding="utf-8"?>
  <kml xmlns="http://earth.google.com/kml/2.0">
  <Document><name>Queensland River Flood Levels</name>""")

  # Create icon styles.
  base = "http://mapvisage.appspot.com/static/floodmap/images/rivers/"
  makeStyle(document, base + "red_smaller.png", "red")
  makeStyle(document, base + "green_smaller.png", "green")
  makeStyle(document, base + "orange_smaller.png", "orange")
  makeStyle(document, base + "ltblue_smaller.png", "ltblue")
  makeStyle(document, base + "gray_smaller.png", "gray")
  makeStyle(document, 'http://mapvisage.appspot.com/static/floodmap/images/' +
            'power-outage.png', 'powerOutage')

  # Add points - TODO(jmcgill) Infowindows?
  for point in data:
    makePoint(document, point)

  document.append("</Document></kml>")
  return "".join(document)

def updateMap():
  from google.appengine.api import memcache
  # TODO(arb): also store in datastore
  memcache.set('qldelec', loadMaps())

def showMap():
  from google.appengine.api import memcache
  return memcache.get('qldelec')

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class UpdatePage(webapp.RequestHandler):
  def get(self):
    updateMap()
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.out.write('OK')

class ShowPage(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'application/vnd.google-earth.kml+xml'
    now = datetime.datetime.utcnow()
    expires = now + datetime.timedelta(minutes=5)
    self.response.headers['Expires'] = (
        expires.strftime('%a, %d %b %Y %H:%M:%S GMT'))
    self.response.headers['Cache-Control'] = 'public, max_age=300'
    self.response.out.write(showMap())

application = webapp.WSGIApplication([('/electricity/update__', UpdatePage),
                                      ('/electricity/json9', ShowPage)], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
